package com.ruoyi.bluebera.task;

import com.mchange.v2.log.MLogger;
import com.ruoyi.bluebera.domain.BizOrders;
import com.ruoyi.bluebera.domain.BizTxScanLogs;
import com.ruoyi.bluebera.service.IBizOrdersService;
import com.ruoyi.bluebera.service.IBizTxScanLogsService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;


@Component("USDTTask")

public class OrderCheckTask {
    private static final String API_URL_TEMPLATE = "https://api.etherscan.io/v2/api?chainid=%s&module=transaction&action=getstatus&txhash=%s&apikey=%s";
    private static final String apiKey = "K487N1EU8R4PIJIF5X6DGB98ICVHASFYPD";

    private static final String EthUsdtchainId = "1";
    private static final String ArbUsdtchainId = "42161";

    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    private static final RestTemplate restTemplate = createRestTemplateWithTimeout(10000, 10000);

    @Autowired
    private IBizOrdersService bizOrdersService;
    @Autowired
    private IBizTxScanLogsService bizTxScanLogsService;

    public void ryNoParams()
    {
        System.out.println("执行无参方法");
    }
    // init--processing--completed

    public void checkAllUSDT() {
        checkUSDTStatus(EthUsdtchainId);
        checkUSDTStatus(ArbUsdtchainId);
    }
    @Transactional
    public void checkUSDTStatus(String chainId){
        // 1. get all preprocessing
        BizOrders bizOrders = new BizOrders();
        bizOrders.setTxStatus("Processing");
        bizOrders.setNetwork(chainId);
        List<BizOrders> list = bizOrdersService.selectBizOrdersList(bizOrders);
        // 2. process according token
        for (BizOrders order : list) {
            Date date = order.getScanLastChecked();
            LocalDateTime scanLastChecked = (date != null)
                    ? LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault())
                    : LocalDateTime.now();
            //logger.warn("usdt scanLastChecked {}", scanLastChecked);
            String txStatus = checkTxStatus(chainId, order.getTxHash(), apiKey, scanLastChecked);
            // change order status and txstatus
            order.setStatus(txStatus);
            if("Completed".equalsIgnoreCase(txStatus)) {
                order.setTxStatus(txStatus);
                //logger.warn("bera updated order={}", order);
                // add content to tx log
                BizTxScanLogs bizTxScanLogs = new BizTxScanLogs();
                /*
                amount DECIMAL(36, 18) default NULL COMMENT '数量',
                bluebera_amount DECIMAL(36, 18) default NULL COMMENT '兑换的bluebera数量',
                rate_to_bluebera DECIMAL(18, 8) default NULL COMMENT '兑换bluebera汇率',
                 */
                // todo -- need tx info
                bizTxScanLogs.setOrderId(order.getId());
                //bizTxScanLogs.setPaymentAddress(order.getWalletAddress());
                bizTxScanLogs.setTxHash(order.getTxHash());
                bizTxScanLogs.setTokenSymbol(order.getTokenSymbol());
                bizTxScanLogs.setNetwork(order.getNetwork());

                //bizTxScanLogs.setAmount(order.getAmountPaid());
                bizTxScanLogs.setBlueberaAmount(order.getBlueberaAmount());
                //bizTxScanLogs.setRateToBluebera(order.getRateToBluebera());
                bizTxScanLogs.setScannedAt(new Date());
                bizTxScanLogsService.insertBizTxScanLogs(bizTxScanLogs);
            }
            bizOrdersService.updateBizOrders(order);
        }

    }
    /**
     *
     * @param chainId
     * @param txHash
     * @param apiKey
     * @param scanLastChecked
     * @return
     *
     * {
     *    "status":"1",
     *    "message":"OK",
     *    "result":{
     *       "isError":"1",
     *       "errDescription":"Bad jump destination"
     *    }
     * }
     * 其中
     * The isError field returns 0 for successful transactions and 1 for failed transactions.
     */
    public static String checkTxStatus(String chainId, String txHash, String apiKey, LocalDateTime scanLastChecked) {

        String url = String.format(API_URL_TEMPLATE, chainId, txHash, apiKey);

        long pastSeconds = 5*60*1000;  // eth_usdt
        if(ArbUsdtchainId.equalsIgnoreCase(chainId)){
            pastSeconds = 2*60*1000; // arb_usdt
        }
        try {
            ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
            if (response.getStatusCode().is2xxSuccessful()) {
                JSONObject json = JSON.parseObject(response.getBody());

                String status = json.getString("status");
                JSONObject result = json.getJSONObject("result");
                String isError = result.getString("isError");  // 0 -- successful   1 -- failed
                String errDescription = result.getString("errDescription");

                System.out.println("API Status: " + status);
                System.out.println("isError: " + isError + ", Description: " + errDescription);

                // 判断：API 响应正常，且超过时间限制
                if ("1".equals(status)) {
                    LocalDateTime now = LocalDateTime.now();
                    long secondsPassed = Duration.between(scanLastChecked, now).getSeconds();
                    // rate and token number check
                    if (secondsPassed > pastSeconds) {
                        return "Completed";
                    }
                }
            } else {
                System.err.println("HTTP error: " + response.getStatusCode());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "Porcessing";
    }

    private static RestTemplate createRestTemplateWithTimeout(int connectTimeoutMillis, int readTimeoutMillis) {
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        factory.setConnectTimeout(connectTimeoutMillis);
        factory.setReadTimeout(readTimeoutMillis);
        return new RestTemplate(factory);
    }


    public static void main(String[] args) {
        // 示例调用
        String chainId = "1";
        String txHash = "0xf3143aabf15c05f1f19d649de11e54fe0ffc005032112bab86ae5cc5acf28277";
        String apiKey = "K487N1EU8R4PIJIF5X6DGB98ICVHASFYPD";
        /*
        https://etherscan.io/tx/0xf3143aabf15c05f1f19d649de11e54fe0ffc005032112bab86ae5cc5acf28277
        https://arbiscan.io/tx/0x1d237bb08c4687a85d556bddc533c9a37bc5b1a36b26280f142fae6079b0c9f7

         */

        // 假设上次检查时间是 30 秒前
        LocalDateTime scanLastChecked = LocalDateTime.now().minusSeconds(30);
        long requiredPastSeconds = 20;

        String txStatus = checkTxStatus(chainId, txHash, apiKey, scanLastChecked);
        System.out.println(chainId+ " 最终状态: " + txStatus);
        // arb-usdt
        chainId = "42161";
        txHash = "0x1d237bb08c4687a85d556bddc533c9a37bc5b1a36b26280f142fae6079b0c9f7";
        scanLastChecked = LocalDateTime.now().minusSeconds(30);
        requiredPastSeconds = 20;

        txStatus = checkTxStatus(chainId, txHash, apiKey, scanLastChecked);
        System.out.println(chainId+ " 最终状态: " + txStatus);
    }
}
